﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using FFmpegVideoClip.Configuration;
using FFmpegVideoClip.Processing;

namespace FFmpegVideoClip.Lib.TaskFlowProcessor
{
    public class MergeTaskFlow : TaskFlowAbstract
    {
        Window? m_window;
        public MergeTaskFlow() { }
        public MergeTaskFlow(Action<double, double> ProgressChangeEvent, Window? window = null)
        {
            OnProgressChange = ProgressChangeEvent;
            m_window = window;
        }
        public override object? Data => throw new NotImplementedException();
        private bool IsComplete = false;
        private double TotalSeconds;
        public override void Execute(List<TaskFlowAbstract> FlowList, TaskFlowAbstract? Previous, params object[] args)
        {
            Dictionary<Clip, LosslessSplitTask[]>? dic = FlowList.FirstOrDefault(p => p is SplitTaskFlow)?.Data as Dictionary<Clip, LosslessSplitTask[]>;
            if (dic == null)
                return;

            IEnumerable<KeyValuePair<Clip, LosslessSplitTask[]>> CanBeMerged = dic.Where(p => p.Value.All(p => !p.IsError));
            LosslessMergeTask[] tasks = CanBeMerged.Select(p => new LosslessMergeTask(p.Key)).ToArray();
            IsComplete = false;
            CalculateProgress(tasks);
            try
            {
                Parallel.ForEach(tasks, new ParallelOptions { MaxDegreeOfParallelism = Config.MaxThread, CancellationToken = Tools.CurrentCancelToken!.Token }, p => 
                {
                    p.Execute();
                    if (Config.AutoClearCache)
                    {
                        string wpd = Path.GetDirectoryName(((Clip)p.SourceData!).Fragments.First().TempWritePath) ?? string.Empty;
                        if (Directory.Exists(wpd))
                            Directory.Delete(wpd, true);
                    }
                });
                IsError = false;
            }
            catch (OperationCanceledException) { }
            catch (Exception exc)
            {
                LogManage.WriteExceptionInfo($"[{nameof(MergeTaskFlow)}] 异常：", exc, true);
            }
            finally { IsComplete = true; }
        }

        private void CalculateProgress(IEnumerable<LosslessMergeTask> tasks)
        {
            TotalSeconds = tasks?.Count() ?? 0;
            Task.Run(() =>
            {
                while (!IsComplete)
                {
                    //OnProgressChange?.Invoke(TotalSeconds,(TotalSeconds - (tasks?.Sum(p => p.ProcessorTime.TotalSeconds) ?? 0)) / TotalSeconds);
                    OnProgressChange?.Invoke(TotalSeconds,tasks?.Sum(p => p.ProcessorTime.TotalSeconds) ?? 0);
                    Thread.Sleep(1000);
                }
            });
        }

    }


}
